
#include <string.h>
#include "lib/type.h"

#define IDLE_LEVLE		1
#define PULSE_LEVLE		!IDLE_LEVLE

#define EDGE_NONE		0
#define IDLE_TO_PULSE	1
#define PULSE_TO_IDLE	2	

#define COUNT_MAX			0XFFFF	
#define DATA_BUFF_MAX_LEN	8	

#define IR_TICK_TIME_IN_US			40UL						//40us/tick

#define SYNC_PULSE_TIME_TICK		6000UL		
#define SYNC_IDLE_TIME_TICK			7320UL

#define BIT0_PULSE_TIME_TICK		530UL
#define BIT0_IDLE_TIME_TICK			(2000-530)

#define BIT1_PULSE_TIME_TICK		530UL
#define BIT1_IDLE_TIME_TICK			(4000-530)

#define END_PULSE_TIME_TICK			530UL
#define END_IDLE_TIME_TICK			(8000-530)

#define ALLOW_ERR_PERCENT			15UL

//repeat: PULSE 9000us + IDLE 2200us PULSE 560us + IDLE 96000us
//1 SYNC + 32 BIT + 1 END + repeat + repeat ....

static uint8_t (*bsp_ir_receive_hal_read_level_callback)(void) = 0;
static uint16_t idle_count = 0;
static uint16_t pulse_count = 0;
static uint8_t last_pin_level = 0;
static uint8_t bit_i = 0;
static uint8_t sync_rec_ok_falg = 0;

uint8_t bsp_ir_receive_finish_receive_falg = 0;
uint8_t bsp_ir_receive_buff[DATA_BUFF_MAX_LEN] = {0};
uint8_t bsp_ir_receive_buff_len = 0;
void (*bsp_ir_receive_receive_finish_callbakc)(void) = 0;

uint8_t ii = 0;
uint16_t temp = 0;
void bsp_ir_receive_tick_handler(void)
{
   	uint8_t temp_pin_level ;
	uint8_t edge;
	uint16_t bit_time;

	if(bsp_ir_receive_finish_receive_falg == 1){
		return;
	}
	
	temp_pin_level = bsp_ir_receive_hal_read_level_callback();
	edge = EDGE_NONE;
	if(temp_pin_level == IDLE_LEVLE){
		if(idle_count <= COUNT_MAX){
			idle_count++;
		}
		if(last_pin_level == PULSE_LEVLE){
			edge = PULSE_TO_IDLE;
		}
	}
	else{
		if(pulse_count <= COUNT_MAX){
			pulse_count++;
		}
		if(last_pin_level == IDLE_LEVLE){
			edge = IDLE_TO_PULSE;
		}
	}
	last_pin_level = temp_pin_level;

	if(edge == PULSE_TO_IDLE){
	}
	else if(edge == IDLE_TO_PULSE){
		bit_time = idle_count + pulse_count;
		if((bit_time >= ((SYNC_PULSE_TIME_TICK+SYNC_IDLE_TIME_TICK) - (((SYNC_PULSE_TIME_TICK+SYNC_IDLE_TIME_TICK)*ALLOW_ERR_PERCENT)/100))/IR_TICK_TIME_IN_US)
		&&(bit_time <= ((SYNC_PULSE_TIME_TICK+SYNC_IDLE_TIME_TICK) + (((SYNC_PULSE_TIME_TICK+SYNC_IDLE_TIME_TICK)*ALLOW_ERR_PERCENT)/100))/IR_TICK_TIME_IN_US)){
			//rec sync head
//			bit_state = RECEIVE_SYNC;
			bit_i = 0;
			bsp_ir_receive_buff_len = 0;
			bsp_ir_receive_buff[bsp_ir_receive_buff_len] = 0;
			sync_rec_ok_falg = 1;
//			if(bsp_rf_receive_ing_call_back != 0){
//				bsp_rf_receive_ing_call_back();
//			}
		}
		else if((bit_time >= ((BIT0_PULSE_TIME_TICK+BIT0_IDLE_TIME_TICK) - (((BIT0_PULSE_TIME_TICK+BIT0_IDLE_TIME_TICK)*ALLOW_ERR_PERCENT)/100))/IR_TICK_TIME_IN_US)
		&&(bit_time <= ((BIT0_PULSE_TIME_TICK+BIT0_IDLE_TIME_TICK) + (((BIT0_PULSE_TIME_TICK+BIT0_IDLE_TIME_TICK)*ALLOW_ERR_PERCENT)/100))/IR_TICK_TIME_IN_US)){
			//rec bit 0
//			bit_state = RECEIVE_BIT0;
			if(sync_rec_ok_falg == 1){
				bit_i++;
			}
		}
		else if((bit_time >= ((BIT1_PULSE_TIME_TICK+BIT1_IDLE_TIME_TICK) - (((BIT1_PULSE_TIME_TICK+BIT1_IDLE_TIME_TICK)*ALLOW_ERR_PERCENT)/100))/IR_TICK_TIME_IN_US)
		&&(bit_time <= ((BIT1_PULSE_TIME_TICK+BIT1_IDLE_TIME_TICK) + (((BIT1_PULSE_TIME_TICK+BIT1_IDLE_TIME_TICK)*ALLOW_ERR_PERCENT)/100))/IR_TICK_TIME_IN_US)){
			//rec bit 1
//			bit_state = RECEIVE_BIT1;
			if(sync_rec_ok_falg == 1){
				bsp_ir_receive_buff[bsp_ir_receive_buff_len] |= 0x01<<bit_i; //the 8 bit cpu was allowed move data in16 bit only, if receive_byte is more then 16 bit, there will be a error happened
				bit_i++;
			}
		}
//		else if((bit_time >= ((END_PULSE_TIME_TICK+END_IDLE_TIME_TICK) - (((END_PULSE_TIME_TICK+END_IDLE_TIME_TICK)*ALLOW_ERR_PERCENT)/100))/IR_TICK_TIME_IN_US)
//		&&(bit_time <= ((END_PULSE_TIME_TICK+END_IDLE_TIME_TICK) + (((END_PULSE_TIME_TICK+END_IDLE_TIME_TICK)*ALLOW_ERR_PERCENT)/100))/IR_TICK_TIME_IN_US)){
////			bit_state = RECEIVE_END;
//			sync_rec_ok_falg = 0;
//			bsp_ir_receive_finish_receive_falg = 1;
//			if(bsp_ir_receive_receive_finish_callbakc != 0){
//				bsp_ir_receive_receive_finish_callbakc();
//			}
//		}
		else{
			bit_i = 0;
			bsp_ir_receive_buff_len = 0;
			bsp_ir_receive_buff[bsp_ir_receive_buff_len] = 0;
			sync_rec_ok_falg = 0;
		}
		pulse_count = 0;
		idle_count = 0;

		if(bit_i == 8){
			if(bsp_ir_receive_buff_len < DATA_BUFF_MAX_LEN){
				bsp_ir_receive_buff_len++;
				bsp_ir_receive_buff[bsp_ir_receive_buff_len] = 0;
			}
			bit_i = 0;
		}
	}
	else{
		if(sync_rec_ok_falg == 1){
			if((last_pin_level == IDLE_LEVLE)&&
			(idle_count + pulse_count >=
			((END_PULSE_TIME_TICK+END_IDLE_TIME_TICK) - (((END_PULSE_TIME_TICK+END_IDLE_TIME_TICK)*ALLOW_ERR_PERCENT)/100))/IR_TICK_TIME_IN_US)){
	//			bit_state = RECEIVE_END;
				sync_rec_ok_falg = 0;
				bsp_ir_receive_finish_receive_falg = 1;
				if(bsp_ir_receive_receive_finish_callbakc != 0){
					bsp_ir_receive_receive_finish_callbakc();
				}
			}
		}
	}
}


void bsp_ir_receive_init(void (*bsp_ir_receive_hal_init_callbakc_handler)(void),
						uint8_t (*bsp_ir_receive_hal_read_level_callbakc_handler)(void))
{
	if(bsp_ir_receive_hal_init_callbakc_handler != 0){
		bsp_ir_receive_hal_init_callbakc_handler();
	}
	
	bsp_ir_receive_hal_read_level_callback = bsp_ir_receive_hal_read_level_callbakc_handler;
	idle_count = 0;
	pulse_count = 0;
	
	bsp_ir_receive_finish_receive_falg = 0;
	bsp_ir_receive_buff_len = 0;
}